﻿#include "CommonFunc.h"

#include "DataInfo.h"

#include <QJsonDocument>
#include <QJsonArray>
#include <QNetworkAccessManager>
#include <QNetworkReply>

#include <QDebug>

void createNetworkAccessManager(QObject *parent)
{
    assert(parent != nullptr);

    g_httpManager = new QNetworkAccessManager(parent);
    g_httpManager->connect(g_httpManager, &QNetworkAccessManager::finished, [](QNetworkReply *reply){
        do{
            if (reply->error() != QNetworkReply::NoError) {
                qDebug() << "error:" << reply->error();
                g_httpReplayResult.first = -1;
                g_httpReplayResult.second = "Http failed!";
                break;
            }

            int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            if (statusCode != 200) {
                const QByteArray &reason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray();
                qWarning() << "ERROR, the http status code is not 200, http reason phrase: " << reason.constData();
                g_httpReplayResult.first = -1;
                g_httpReplayResult.second = "Http failed!";
                break;
            }

            qDebug() << "url:" << reply->url();
            QByteArray bytes = reply->readAll();
            qDebug() << bytes;
            QJsonObject json = QJsonDocument::fromJson(bytes).object();
            g_httpReplayResult.first = json["code"].toInt();
            g_httpReplayResult.second = json["message"].toString();
            if (json["code"].toInt() != 0) {
        //        QMessageBox::information(this,"login", json["message"].toString());
                qDebug() << "have a error unsucessful !";
            }

            if (readPersonID(json))
            {
                // login Info
                updateAllMessageInfo();
                executeFuncFromID(XUI_Login);
    //            sendGetThresholdInfo();
            }
            else if (readThresholdInfo(json))
            {
                executeFuncFromID(XUI_ShowThreshold);
                sendSensorStatusInfo();
            }
            else if (readSensorStatusInfo(json))
            {
                executeFuncFromID(XUI_ShowStatus);
                sendProductLine();
            }
            else if (readProductLineInfo(json))
            {
                // product_line_list
                executeFuncFromID(XProductLine);
//                qDebug() << "**** read product line " << g_vecProductInfo.size();
            }
            else if (readGateWayInfo(json))
            {
                // product_line_list
    //            executeFuncFromID(XUI_GateWayManage);
                executeFuncFromID(XShowGateWay);
                g_iGateWayID  = -1;
                g_mapGroupIdToListSensor.clear();
            }
            else if (readSensorDeviceInfo(json))
            {
    //            executeFuncFromID(XUI_DeviceManage);
                executeFuncFromID(XShowDevice);
                executeFuncFromID(XShowAbnormal);
                executeFuncFromID(XShowSpeed);
            }
        } while (false);

        // 登录结果返回
        if (reply->url() == QUrl(QString(URI) + "/api/client/user_login")) {
            executeFuncFromID(XLogin_Result);
        } else if (reply->url() == QUrl(QString(URI) + "/api/client/set_threshold")) {
            executeFuncFromID(XSetThreshold_Result);
        }

    });
}


bool readPersonID(const QJsonObject &json)
{
    if (!json.contains("person_id"))
    {
        return false;
    }

    g_person_id = json["person_id"].toInt();

    return true;
}

void sendLoginInfo(const QString& strName, const QString& password)
{
    g_person_id = -1;

    QNetworkRequest request;
    request.setUrl(QUrl(QString(URI) + "/api/client/user_login"));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    QJsonObject data
    {
        {"username",strName},
        {"password",password}
    };
    QJsonDocument document(data);
    request.setHeader(QNetworkRequest::ContentLengthHeader, document.toJson().length());
    qDebug() << "data:" <<document.toJson();

    g_httpManager->post(request, document.toJson());
}

bool readProductLineInfo(const QJsonObject &json)
{
    if (!checkPersonID())
    {
        return false;
    }

    if (!json.contains("product_line_list"))
    {
        return false;
    }

    if (!json["product_line_list"].isArray())
    {
        return false;
    }

    QJsonArray array = json["product_line_list"].toArray();
    g_vecProductInfo.resize(array.size());
    for (int i = 0; i < array.size(); ++i)
    {
        QJsonObject cur = array[i].toObject();
        ProductInfo info;
        info.id = cur["id"].toInt();
        info.isEnable= cur["is_enable"].toBool();
        info.strName = cur["name"].toString();
        info.normalCount = cur["normalCount"].toInt();
        info.otherCount= cur["otherCount"].toInt();
        info.slowCount = cur["slowCount"].toInt();
        info.stopCount= cur["stopCount"].toInt();
        g_vecProductInfo[i] = info;
    }
    return true;
}

void appendTypeToFunc(int type, std::function<void ()> func)
{
    if (func)
    {
        g_mapIntToFunc[type] = func;
    }
}

void removeTypeToFunc(int type)
{
    g_mapIntToFunc.remove(type);
}

std::function<void ()> getFuncFromID(int type)
{
    if (g_mapIntToFunc.contains(type))
    {
        return g_mapIntToFunc[type];
    }

    return std::function<void ()>();
}

void sendProductLine()
{
    if (!checkPersonID())
    {
        return;
    }

    QNetworkRequest request;
    QString url = QString("%1/api/client/product_line?person_id=%2").arg(URI).arg(g_person_id);
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    g_httpManager->get(request);
}

void sendGateWayInfo()
{
    if (!checkPersonID())
    {
        return;
    }
    if (!checkProductLineID())
    {
        return;
    }

    QNetworkRequest request;
    QString url = QString("%1/api/client/product_device?product_line_id=%2").arg(URI).arg(g_iProductLineID);
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    g_httpManager->get(request);
}

bool readGateWayInfo(const QJsonObject &json)
{
    if (!checkPersonID())
    {
        return false;
    }

    if (!json.contains("product_device_list"))
    {
        return false;
    }

    if (!json["product_device_list"].isArray())
    {
        return false;
    }

    QJsonArray array = json["product_device_list"].toArray();
    g_vecGateWay.resize(array.size());
    for (int i = 0; i < array.size(); ++i)
    {
        QJsonObject cur = array[i].toObject();

        GateWay info;
        info.id = cur["id"].toInt();
        info.isEnable= cur["is_enable"].toBool();
        info.strName = cur["name"].toString();

        g_vecGateWay[i] = info;
    }
//    qDebug() << "**** size:  " << g_vecProductDevice.size();


    return true;
}

void sendSensorDeviceRequest()
{
    if (!checkPersonID())
    {
        return ;
    }

    if (!checkProductLineID())
    {
        return;
    }
    if (!checkGateWayID())
    {
        return;
    }
    QNetworkRequest request;
    QString url = QString("%1/api/client/product_sensor?product_device_id=%2").arg(URI).arg(g_iGateWayID);
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    g_httpManager->get(request);

}

bool readSensorDeviceInfo(const QJsonObject &json)
{
    if (!checkPersonID())
    {
        return false;
    }

    if (!json.contains("product_sensor_group_list"))
    {
        return false;
    }

    if (!json["product_sensor_group_list"].isArray())
    {
        return false;
    }

    QJsonArray array = json["product_sensor_group_list"].toArray();
    for (int i = 0; i < array.size(); ++i)
    {
        QJsonObject group = array[i].toObject();
        if (!group.contains("group_code") || !group.contains("sensor_list"))
        {
            continue;
        }

        int gID = group["group_code"].toInt();
        QJsonArray ssArray = group["sensor_list"].toArray();
        for (int j = 0; j < ssArray.size(); ++j)
        {
            QJsonObject ssObj = ssArray[j].toObject();
            Sensor ss;
            ss.id = ssObj["id"].toInt();
            ss.data = ssObj["data"].toInt();
            ss.cell_code = ssObj["cell_code"].toString();
            ss.name = ssObj["name"].toString();
            ss.status = ssObj["status"].toString();
//"cell_code\":\"A\",\"data\":0,\"id\":1,\"name\":\"101\",\"status\":\"stop\"
            g_mapGroupIdToListSensor[gID].push_back(ss);
        }
    }


    return true;
}

void updateAllMessageInfo()
{
    if (g_person_id == -1)
    {
        return;
    }

    if (g_iGateWayID != -1)
    {
        g_mapGroupIdToListSensor.clear();
        sendSensorDeviceRequest();
        return;
    }

    if (g_iProductLineID != -1)
    {
        g_vecGateWay.clear();
        sendGateWayInfo();
        return;
    }

    if (g_isUpdateMessageInfo)
    {
        qDebug() << __FUNCTION__ << "  warning update info false : ";
    }

    g_isUpdateMessageInfo = true;

    sendGetThresholdInfo();
}

void sendGetThresholdInfo()
{
    if (!checkPersonID())
    {
        return;
    }
    QNetworkRequest request;
    QString url = QString("%1/api/client/get_threshold").arg(URI);
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    g_httpManager->get(request);
}

void executeFuncFromID(int id)
{
    if (auto func = getFuncFromID(id))
    {
        func();
    }
}

bool readThresholdInfo(const QJsonObject &json)
{
    if (!checkPersonID())
    {
        return false;
    }

    if (!json.contains("threshold"))
    {
        return false;
    }

    g_iThreshold = json["threshold"].toInt(0);

    return true;
}

bool readSensorStatusInfo(const QJsonObject &json)
{
    if (!checkPersonID())
    {
        return false;
    }

    if (!json.contains("sensor_status"))
    {
        return false;
    }

    if (!json["sensor_status"].isObject())
    {
        return false;
    }

//{\"normalCount\":5,\"otherCount\":0,\"slowCount\":0,\"stopCount\":9}
    QJsonObject obj = json["sensor_status"].toObject();
    g_sensorStatus[0] = obj["normalCount"].toInt(0);
    g_sensorStatus[1] = obj["otherCount"].toInt(0);
    g_sensorStatus[2] = obj["slowCount"].toInt(0);
    g_sensorStatus[3] = obj["stopCount"].toInt(0);

    return true;
}

void sendChangeThresholdValue(int value)
{
    QNetworkRequest request;
    request.setUrl(QUrl(QString(URI) + "/api/client/set_threshold"));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    QJsonObject data
    {
        {"threshold",value}
    };
    QJsonDocument document(data);
    request.setHeader(QNetworkRequest::ContentLengthHeader, document.toJson().length());
    qDebug() << "data:" <<document.toJson();

    g_httpManager->post(request, document.toJson());
}

void sendSensorStatusInfo()
{
    if (!checkPersonID())
    {
        return;
    }
    QNetworkRequest request;
    QString url = QString("%1/api/client/get_sensor_status?person_id=%2").arg(URI).arg(g_person_id);
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    g_httpManager->get(request);
}

bool checkPersonID()
{
    if (g_person_id == -1)
    {
        return false;
    }

    return true;
}

bool checkProductLineID()
{
    if (g_iProductLineID == -1)
    {
        return false;
    }

    return true;
}

bool checkGateWayID()
{
    if (g_iGateWayID == -1)
    {
        return false;
    }

    return true;
}
